package app.displayTree.optimizer {
    import copyengine.infoTree.meta.CESAnimationEachFrameInfoMeta;
    import copyengine.infoTree.meta.CESDisplayObjectMeta;
    import copyengine.infoTree.meta.CESFileMeta;
    import copyengine.infoTree.meta.CESMovieClipMeta;
    import copyengine.infoTree.meta.CESShapeMeta;
    import copyengine.infoTree.meta.CESSpriteMeta;
    import copyengine.log.CELog;

    import flash.geom.Matrix;

    import org.as3commons.lang.StringUtils;

    public final class DisplayTreeOptimizer {
        public function DisplayTreeOptimizer() {
        }

        //=============================================//
        //================= OPTIMIZE ====================//
        //=============================================//

        /**
         * 对某一个Meta显示树层级结构进行优化</br>
         * <b>注意!!!目前版本不支持滤镜</b>
         * <li>如果某一个Sprite节点下仅有一个Child,且这个Child为一个Shape,则删除Sprite节点仅保留Shape节点
         */
        public function optimize(_meta:CESFileMeta):void {
            var isContinueOptimize:Boolean = true;
            while (isContinueOptimize) {
                isContinueOptimize = doOptimize(_meta);
            }
        }

        /**
         *While-True循环,遍历调用该函数,每次调用优化一次及返回
         * <li>TRUE        表示当前优化了一次,while循环需要继续
         * <li>FALSE        表示当前没有做任何优化,while循环可以结束
         */
        private function doOptimize(_meta:*):Boolean {
            if (_meta is CESMovieClipMeta) {
                return doOptimizeMovieClipMeta(_meta as CESMovieClipMeta);
            }
            else if (_meta is CESSpriteMeta) {
                return doOptimizeSpriteMeta(_meta as CESSpriteMeta);
            }
            else if (_meta is CESFileMeta) {
                return doOptimizeFileMeta(_meta as CESFileMeta);
            }
            return false;
        }

        private function doOptimizeFileMeta(_meta:CESFileMeta):Boolean {
            for (var symbolKey:String in _meta.allSubSymbolDic) {
                var optimzeResult:CESDisplayObjectMeta = checkAndOptimizeMeta(_meta.allSubSymbolDic[symbolKey]);
                if (optimzeResult) {
                    _meta.allSubSymbolDic[symbolKey] = optimzeResult;
                    return true;
                }
                else {
                    var childOptimizeResult:Boolean = doOptimize(_meta.allSubSymbolDic[symbolKey]);
                    if (childOptimizeResult == true) {
                        return true;
                    }
                }
            }
            return false;
        }


        private function doOptimizeSpriteMeta(_meta:CESSpriteMeta):Boolean {
            for (var childIndex:int = 0; childIndex < _meta.childMetaArray.length; childIndex++) {
                var optimizeResult:CESDisplayObjectMeta = checkAndOptimizeMeta(_meta.childMetaArray[childIndex]);
                if (optimizeResult) {
                    _meta.childMetaArray[childIndex] = optimizeResult;
                    return true;
                }
                else {
                    var childOptimizeResult:Boolean = doOptimize(_meta.childMetaArray[childIndex]);
                    if (childOptimizeResult == true) {
                        return true;
                    }
                }
            }
            return false;
        }

        private function doOptimizeMovieClipMeta(_meta:CESMovieClipMeta):Boolean {
            for (var childIndex:int = 0; childIndex < _meta.allTargetMetaArray.length; childIndex++) {
                var optimizeResult:CESDisplayObjectMeta = checkAndOptimizeMeta(_meta.allTargetMetaArray[childIndex]);
                if (optimizeResult) {
                    _meta.allTargetMetaArray[childIndex] = optimizeResult;
                    return true;
                }
            }
            return false;
        }


        private function checkAndOptimizeMeta(_meta:CESDisplayObjectMeta):CESDisplayObjectMeta {
            if (_meta is CESSpriteMeta) {
                var spMeta:CESSpriteMeta = _meta as CESSpriteMeta;

                //如果Sp仅有一个子且该child为一个shape
                if (spMeta.childMetaArray.length == 1 && spMeta.childMetaArray[0] is CESShapeMeta) {
                    //Sp的名字必须为Instance,标明Sp没有取过名字,否则Sp的名字将会被Shap的名字覆盖
                    //一般不会存在Sprite没有名字但是Shape有名字情况,因为这样会定位不到Shape的
                    //但是如果Root节点下仅仅有一个Shape就会存在这种情况,此时仍旧不可以优化节点
                    if (StringUtils.startsWith(spMeta.name, "instance") && StringUtils.startsWith(spMeta.childMetaArray[0].name, "instance")) {
                        var shapeMeta:CESShapeMeta = spMeta.childMetaArray[0] as CESShapeMeta;

                        if (shapeMeta.frameTransformMatrixArray.length == 1 && spMeta.frameTransformMatrixArray.length == 1) {
                            var shapeTransFormMatrix:Matrix = (shapeMeta.frameTransformMatrixArray[0] as CESAnimationEachFrameInfoMeta).getMatrix();
                            var spTransFormMatrix:Matrix = (spMeta.frameTransformMatrixArray[0] as CESAnimationEachFrameInfoMeta).getMatrix();

                            var combinMatrix:Matrix = new Matrix();
                            combinMatrix.concat(shapeTransFormMatrix);
                            combinMatrix.concat(spTransFormMatrix);

                            (shapeMeta.frameTransformMatrixArray[0] as CESAnimationEachFrameInfoMeta).setMatrix(combinMatrix);

                            //使用当前的Shape替换原有的Sp,所以当前的Shape继承原有Sp的层级
                            shapeMeta.childIndex = spMeta.childIndex;

                            return shapeMeta;
                        }
                        else {
                            //理论情况不会出现Shape内的FrameInfo超过1个,因为在MovieClip中如果对一个Shape进行动画
                            CELog.err("DisplayTreeOptimizer->checkAndOptimizeMeta shape or sprite resource.meta frameInfoLength != 1 ");
                            return null;
                        }
                    }

                }
            }
            return null;
        }

    }
}
